<?php

namespace app\api\controller;

use think\facade\Db;
use think\facade\Request;
use ouyangke\Ticket;
use Symfony\Component\VarDumper\Cloner\Data;

use function PHPSTORM_META\type;

class Api
{
    // Access to XMLHttpRequest at 'http://www.tp.com/index.php/api/Api/index' 
    // from origin 'http://localhost:8080' has been blocked by CORS policy: No 
    // 'Access-Control-Allow-Origin' header is present on the requested resource.
    // 错误信息：是因为前后端分离导致的。前后端 前端和后端的域名不是一个。不是一个，就会出现这种错误。
    // 跨域名访问的安全错误提示

    private $uid;
    public function __construct()
    {
        // 使用php的header函数，设置为*，全部能访问
        header("Access-Control-Allow-Origin:*");
        $token = Request::header('token');
        $this->uid = Ticket::get($token, 'ouyangke');
        // 双重保险，其实找不到$uid上面就报错结束php了
        if (!(Db::table('oyk_user')->where('uid', $this->uid)->find())) {
            formatting([
                'code' => -1,
                'message' => 'token验证错误'
            ])->send();
            exit;
        }
    }

    public function index()
    {
        // 如何写一个 前端数据接口呢？app、小程序、vue
        // 接口：让2个以上的项目进行数据联通，数据交互
        // 多个语言 必须有统一的格式， 最后返回值，必须多种语言都能使用

        // 接口的统一数据格式是 json

        // php有json的函数 
        // json_encode 把php的数据加密成json格式
        // json_decode 把json格式转为 php数据格式

        // $arr = [
        //     "ouyangke" => "欧阳克",
        //     "miejue" => "灭绝师太",
        //     "php" => [
        //         "ouyangke",
        //         "miejue"
        //     ],
        //     "tianpeng" => "朱天蓬"
        // ];
        // json格式，是文本，我们就可以echo
        // {"ouyangke":"\u6b27\u9633\u514b","miejue":"\u706d\u7edd\u5e08\u592a","tianpeng":"\u6731\u5929\u84ec"}
        // echo json_encode($arr);
        // 1、接口 必须用json返回数据
        // 2、用数组 转为json数据
        return tryCatchWrapper(
            function () {
                $ad = Db::table('oyk_adver')->where('status', 1)->order('sort DESC')->select()->toArray();
                $lists = Db::table('oyk_shop_lists')->where('status', 1)->order('add_time DESC')->limit(6)->select()->toArray();
                foreach ($lists as &$v) {
                    $img = explode(';', $v['img']);
                    $v['img_s'] = $img[0];
                }
                $data = [
                    'ad' => $ad,
                    'lists' => $lists
                ];
                return formatting([
                    'code' => 1,
                    'data' => $data
                ]);
            }
        );
    }

    public function goods_index()
    {
        return tryCatchWrapper(
            function () {
                $cat = DB::table('oyk_shop_cat')->where('status', 1)->order('pid,sort DESC')->select()->toArray();
                $temp = [];
                foreach ($cat as $v) {
                    if ($v['pid'] == 0) {
                        $temp[$v['cid']] = $v;
                    } else {
                        $temp[$v['pid']]['son'][] = $v;
                    }
                }
                return formatting([
                    'code' => 1,
                    'data' => array_values($temp)
                ]);
            }
        );
    }


    public function goods_lists()
    {
        return tryCatchWrapper(
            function () {
                $page = input('post.page') ?? 1;
                $id = input('post.id');
                $lists = Db::table('oyk_shop_lists')->where('status', 1)->where('cid', $id)->page($page, 5)->select()->toArray();
                foreach ($lists as &$v) {
                    $img = explode(';', $v['img']);
                    $v['pic'] = $img[0];
                }
                return formatting([
                    'code' => 1,
                    'data' => $lists
                ]);
            }
        );
    }

    // 获取商品详情
    public function goods_details()
    {
        return tryCatchWrapper(
            function () {
                $id = input('post.id');
                // 1单件商品 2多件商品
                $type = input('post.type') ?? 1;
                if ($type == 1) {
                    $details = Db::table('oyk_shop_lists')->where('status', 1)->where('id', $id)->find();
                    if ($details) {
                        $details['img_arr'] = explode(';', $details['img']);
                        $details['info_arr'] = explode(';', $details['info']);
                    }
                } else if ($type == 2) {
                    $id = explode(';', $id);
                    $details = Db::table('oyk_shop_lists')->where('status', 1)->where('id', 'in', $id)->select();
                }
                return formatting([
                    'code' => 1,
                    'data' => $details
                ]);
            }
        );
    }

    /* 
        添加购物车 POST
        必传sid（商品id）
        可传type add添加 sub减少 默认add
    */

    public function add_cart()
    {
        return tryCatchWrapper(
            function () {
                $uid = $this->uid;
                $sid = input('post.sid');
                $type = input('post.type') ?? 'noChange';
                $check = input('post.check') ?? 0;
                $temp = null;
                $find = DB::table('oyk_cart')->where('uid', $uid)->where('sid', $sid)->find();
                if ($type === 'add') {
                    if (!$find) {
                        DB::table('oyk_cart')->insert([
                            'uid' => $uid,
                            'sid' => $sid,
                            'num' => 1,
                            'status' => 1,
                            'add_time' => time()
                        ]);
                        $temp = 'insert';
                    } else {
                        DB::table('oyk_cart')->where('uid', $uid)->where('sid', $sid)->update([
                            'num' => $find['num'] + 1,
                            'check' => $check
                        ]);
                        $temp = 'updata';
                    }
                } else if ($type === 'sub') {
                    if ($find['num'] <= 1) {
                        DB::table('oyk_cart')->where('uid', $uid)->where('sid', $sid)->delete();
                        $temp = 'delete';
                    } else {
                        DB::table('oyk_cart')->where('uid', $uid)->where('sid', $sid)->update([
                            'num' => $find['num'] - 1,
                            'check' => $check
                        ]);
                        $temp = 'updata';
                    }
                } else if ($type === 'noChange') {
                    if ($find) {
                        DB::table('oyk_cart')->where('uid', $uid)->where('sid', $sid)->update([
                            'check' => $check
                        ]);
                        $temp = 'noChange';
                    }
                }
                return formatting([
                    'code' => 1,
                    'data' =>  $temp
                ]);
            },
            [
                'message' => '添加购物车失败'
            ]
        );
    }

    // 直接购买时 订单页获取单个商品信息接口
    public function shop_one()
    {
        return tryCatchWrapper(
            function () {
                $uid = $this->uid;
                $id = input('post.id');
                $good = DB::table('oyk_shop_lists')->where('id', $id)->find();
                $address = Db::table('oyk_user_address')->where('uid', $uid)->order('is DESC')->select()->toArray();
                return formatting([
                    'code' => 1,
                    'data' =>  ['good' => $good, 'address' => $address]
                ]);
            }
        );
    }

    // 购物车购买 订单页获取多个商品信息接口
    public function shop_many()
    {
        return tryCatchWrapper(
            function () {
                $uid = $this->uid;
                $id = input('post.id');
                $num = input('post.num');
                // 转换成数组
                $id =  explode(';', $id);
                $num = explode(';', $num);
                $good = DB::table('oyk_shop_lists')->where('id', 'in', $id)->select()->toArray();
                $address = Db::table('oyk_user_address')->where('uid', $uid)->order('is DESC')->select()->toArray();
                // 价格等于单价乘以数量
                $total_money = 0;
                foreach ($good as $k => &$v) {
                    $v['order_num'] = $num[$k];
                    $v['money'] = $v['price'] * $num[$k];
                    $total_money += $v['money'];
                }
                $good['total_money'] = $total_money;
                //     $good = DB::table('oyk_shop_lists')->where('id', $id)->find();
                //     $address = Db::table('oyk_user_address')->where('uid', $uid)->order('is DESC')->select()->toArray();
                return formatting([
                    'code' => 1,
                    'data' =>  ['good' => $good, 'address' => $address]
                ]);
            }
        );
    }


    // 购物车下订单
    public function add_order()
    {
        return tryCatchWrapper(
            function () {
                $type = input('post.type');
                if ($type == 1) {
                    // 单件商品
                    $id = input('post.id');
                    $uid = $this->uid;
                    $money = Db::table('oyk_shop_lists')->where('id', $id)->value('price');
                    $order_id = DB::table('oyk_user_order')->insertGetId([
                        'oid' => date('Ymd', time()) . round(1000, 9999),
                        'uid' => $uid,
                        'shop_id' => $id,
                        'money' => $money,
                        'add_time' => time(),
                        'info' => '',
                        'marks' => input('post.marks'),
                        'address' => input('post.address'),
                        'num' => 1,
                    ]);
                } else if ($type == 2) {
                    // 多件商品
                    $uid = $this->uid;
                    $id = input('post.id');
                    $num = input('post.num');
                    // 转换成数组
                    $id =  explode(';', $id);
                    $num = explode(';', $num);
                    // 如果id和num长度不对应，直接返回错误
                    if (count($id) !== count($num)) {
                        return formatting([
                            'code' => -1,
                            'message' => '商品id和数量不对应'
                        ]);
                    }
                    // 计算价格（为保险起见，不要取查询页计算出的价格，下单时重新计算）
                    $good = DB::table('oyk_shop_lists')->where('id', 'in', $id)->select()->toArray();
                    $money = 0;
                    foreach ($good as $k => &$v) {
                        $v['order_num'] = $num[$k];
                        $v['money'] = $v['price'] * $num[$k];
                        $money += $v['money'];
                    }
                    // 数组转字符串
                    $id = implode(';', $id);
                    $num = implode(';', $num);
                    $order_id = DB::table('oyk_user_order')->insertGetId([
                        'oid' => date('Ymd', time()) . round(1000, 9999),
                        'uid' => $uid,
                        'shop_id' => $id,
                        'money' => $money,
                        'add_time' => time(),
                        'info' => '',
                        'marks' => input('post.marks'),
                        'address' => input('post.address'),
                        'num' => $num,
                    ]);
                }
                return formatting([
                    'code' => 1,
                    'data' =>  ['order_id' => $order_id]
                ]);
            },
            [
                'message' => '订单创建失败'
            ]
        );
    }

    // 获取订单信息
    public function get_order()
    {
        return tryCatchWrapper(
            function () {
                $id = input('post.id');
                $order = DB::table('oyk_user_order')->where('id', $id)->find();
                // 检查订单是否合法
                // $status = $this->check_order($id);
                // if ($status) {
                //     return $status;
                // }
                return formatting([
                    'code' => 1,
                    'data' => $order
                ]);
            },
        );
    }

    // 检查订单
    private function check_order($order)
    {
        $uid = $this->uid;
        if (empty($order)) {
            return -1;
        } else if ($order['uid'] !== $uid) {
            // 订单uid和用户id不匹配
            return -2;
        } else if ($order['status'] === 0) {
            return -3;
        } else if ($order['status'] === 2) {
            return -4;
        }
        return 0;
    }

    // 支付订单
    public function pay_order()
    {
        return tryCatchWrapper(
            function () {
                // 真是情况应该是调用微信、支付宝的支付接口，这里就不写了
                $id = input('post.id');
                $is_pay = input('post.is_pay');
                $order = DB::table('oyk_user_order')->where('id', $id)->find();
                // 检查订单是否合法
                $status = $this->check_order($order);
                if ($status === -1 || $status === -2) {
                    return formatting([
                        'code' => -1,
                        'message' =>  '未找到订单', // 订单uid和用户id不匹配
                    ]);
                } else if ($status === -3) {
                    return formatting([
                        'code' => -2,
                        'message' =>  '订单已关闭',
                        'data' => $order
                    ]);
                } else if ($status === -4) {
                    return formatting([
                        'code' => -2,
                        'message' =>  '订单已支付',
                        'data' => $order
                    ]);
                }
                DB::table('oyk_user_order')->where('id', $id)->update([
                    'pay_type' => $is_pay, // 1微信 2支付宝
                    'pay_time' => time(),
                    'status' => 2,
                ]);
                $order = DB::table('oyk_user_order')->where('id', $id)->find();
                return formatting([
                    'code' => 1,
                    'message' => '支付成功',
                    'data' => $order
                ]);
            },
            [
                'message' => '支付失败'
            ]
        );
    }

    // 切换地址
    public function change_addr()
    {
        return tryCatchWrapper(
            function () {
                $id = input('post.id');
                Db::transaction(function () use ($id) {
                    DB::table('oyk_user_address')->where('id', '<>', $id)->update(['is' => 0]);
                    DB::table('oyk_user_address')->where('id', $id)->update([
                        'is' => 1
                    ]);
                });
                return formatting([
                    'code' => 1,
                ]);
            },
        );
    }

    // 用地址id获取地址详情
    public function get_addr()
    {
        return tryCatchWrapper(
            function () {
                $id = input('get.id');
                $address = Db::table('oyk_user_address')->where('id', $id)->order('is DESC')->find();
                return formatting([
                    'code' => 1,
                    'data' => $address
                ]);
            },
        );
    }


    // 购物车
    public function cart_index()
    {
        return tryCatchWrapper(
            function () {
                $uid = $this->uid;
                $cart = DB::table('oyk_cart')->where('uid', $uid)->select()->toArray();
                $goodIds = [];
                if (!empty($cart)) {
                    foreach ($cart as $v) {
                        $goodIds[] = $v['sid'];
                    }
                    // 查询一次性能比较快
                    $goods =  DB::table('oyk_shop_lists')->where('id', 'in', $goodIds)->select()->toArray();
                    // 方法1（不太熟悉php数组高阶函数，双层循环）
                    // foreach ($cart as &$v) {
                    //     // $v.sid === $good.id
                    //     foreach ($goods as $good) {
                    //         if ($v['sid'] === $good['id']) {
                    //             $v['good'] = $good;
                    //         }
                    //     }
                    // }
                    // 方法2 用php方法将数组下标转换为id
                    // $goods = array_column($goods, null, 'id');
                    // foreach ($cart as &$v) {
                    //     $v['good'] = $goods[$v['sid']] ?? null;
                    // }
                    // 方法3 巧妙运用php内置方法 array_search搜索key，array_column将数组key转为为id
                    // foreach ($cart as &$v) {
                    //     $key = array_search($v['sid'], array_column($goods, 'id'));
                    //     if ($key !== false) {
                    //         $v['good'] = $goods[$key];
                    //     }
                    // }
                    // 方法4 php的高阶函数 map返回$v，filter获取到指定的数组，reset获取数组第一个元素
                    $cart = array_map(function ($v) use ($goods) {
                        $good = array_filter($goods, function ($good) use ($v) {
                            return $v['sid'] === $good['id'];
                        });
                        if (!empty($good)) {
                            $v['good'] = reset($good);
                        }
                        if ($v['check'] === 1) {
                            $v['check'] = true;
                        } else {
                            $v['check'] = false;
                        }
                        return $v;
                    }, $cart);
                }
                return formatting([
                    'code' => 1,
                    'data' => $cart
                ]);
            },
        );
    }

    // 订单列表
    public function order_list()
    {
        return tryCatchWrapper(
            function () {
                $uid = $this->uid;
                $list = DB::table('oyk_user_order')->where('uid', $uid)->order('add_time', 'desc')->select()->toArray();
                return formatting([
                    'code' => 1,
                    'data' => $list
                ]);
            },
        );
    }
}
